home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / t_os / chtiff / source / chtiff2.c < prev    next >
Text File  |  1993-07-08  |  7KB  |  274 lines

  1. /*
  2. TownsTIFF ←→ NeXTTIFF コンバーター
  3. ファイル書き出し部分
  4. */
  5.  
  6. #include<stdio.h>
  7. #include<stdlib.h>
  8. #include"define.h"
  9. #define WRITE_SECTION 1
  10. #include"function.h"
  11.  
  12.  
  13. /*
  14. 関数readdataの逆で書き込み用
  15. 同じくintel/Motorolaを吸収する。結局、書き込む値別に関数を作った。
  16. */
  17. void write_BYTE(unsigned long offset, unsigned char data)
  18. {
  19.     unsigned long backup_offset;
  20.  
  21.     if(offset){
  22.         backup_offset=ftell(to.fp);
  23.         fseek(to.fp, offset, SEEK_SET);
  24.         }
  25.     fputc(data, to.fp);
  26.     if(offset) fseek(to.fp, backup_offset, SEEK_SET);
  27.     return;
  28. }
  29.  
  30. void write_SHORT(unsigned long offset, unsigned short data)
  31. {
  32.     unsigned long backup_offset;
  33.  
  34.     if(offset){
  35.         backup_offset=ftell(to.fp);
  36.         fseek(to.fp, offset, SEEK_SET);
  37.         }
  38.  
  39.     if(to.Intel){
  40.         fputc( (data & 0xff), to.fp);
  41.         fputc( (data >> 8)  , to.fp);
  42.         }
  43.     else{
  44.         fputc( (data >>8)   , to.fp);
  45.         fputc( (data & 0xff), to.fp);
  46.         }
  47.  
  48.     if(offset) fseek(to.fp, backup_offset, SEEK_SET);
  49.  
  50.     return;
  51. }
  52.  
  53. void write_LONG(unsigned long offset, unsigned long data)
  54. {
  55.     unsigned long backup_offset;
  56.  
  57.     if(offset){
  58.         backup_offset=ftell(to.fp);
  59.         fseek(to.fp, offset, SEEK_SET);
  60.         }
  61.  
  62.     if(to.Intel){
  63.         fputc( (data    ) & 0xff, to.fp);    /* 最下位8bit */
  64.         fputc( (data>> 8) & 0xff, to.fp);
  65.         fputc( (data>>16) & 0xff, to.fp);
  66.         fputc( (data>>24)       , to.fp);    /* 最上位8bit */
  67.         }
  68.     else{
  69.         fputc( (data>>24)       , to.fp);    /* 最上位8bit */
  70.         fputc( (data>>16) & 0xff, to.fp);
  71.         fputc( (data>> 8) & 0xff, to.fp);
  72.         fputc( (data    ) & 0xff, to.fp);    /* 最下位8bit */
  73.         }
  74.  
  75.     if(offset) fseek(to.fp, backup_offset, SEEK_SET);
  76.     return;
  77. }
  78.  
  79.  
  80.  
  81. /* エントリを一つ書き込む。 */
  82. void write_entry(unsigned short tag, unsigned short type,
  83.                  unsigned long len,  unsigned long value)
  84. {
  85.     write_SHORT(0UL,tag);
  86.     write_SHORT(0UL,type);
  87.     write_LONG (0UL,len);
  88.     switch(type){
  89.         case BYTE_TYPE:
  90.             if( len>4 ) goto LONG;    /* 書き込む値が4バイト以上の時 */
  91.             write_BYTE(0UL, (unsigned char)value );
  92.             fputc(0, to.fp); fputc(0, to.fp); fputc(0, to.fp);
  93.             break;
  94.  
  95.         case SHORT_TYPE:
  96.             if( len>2 ) goto LONG;    /* 書き込む値が4バイト以上の時 */
  97.             write_SHORT(0UL, (unsigned short)value );
  98.             fputc(0, to.fp); fputc(0, to.fp);
  99.             break;
  100.  
  101.         case LONG_TYPE: case RATIONAL_TYPE:
  102.             LONG:
  103.             write_LONG (0UL, value);
  104.         }
  105.  
  106.     /* だらだらかき出すだけ・・・ */
  107. }
  108.  
  109.  
  110. /*
  111. グローバル変数toにしたがってIFDをかき出す。
  112. fpは予めセットされてること
  113. */
  114. void write_IFD(void)
  115. {
  116.     unsigned long Strip_Offset;
  117.     unsigned long Strips_ByteCount;
  118.     unsigned long X_Res;
  119.     unsigned long Y_Res;
  120.     unsigned long Color_Map;
  121.     unsigned long BPS_len;
  122.     unsigned long BPS_offset;
  123.     unsigned int i,j;
  124.  
  125.     /* Resolution の書き込み */
  126.     X_Res=ftell(to.fp);
  127.     Y_Res=X_Res+8;
  128.     write_LONG(0UL,to.X_Resolution.bunsi);
  129.     write_LONG(0UL,to.X_Resolution.bunbo);
  130.     write_LONG(0UL,to.Y_Resolution.bunsi);
  131.     write_LONG(0UL,to.Y_Resolution.bunbo);
  132.  
  133.     /* Strip_Offset & Strips_ByteCount の書き込み */
  134.     if(to.Strips!=1){
  135.         Strip_Offset = ftell(to.fp);
  136.         for(i=0; i<to.Strips; i++)
  137.             write_LONG(0UL, *(to.Strip_Offset + i) );
  138.         Strips_ByteCount = ftell(to.fp);
  139.         for(i=0; i<to.Strips; i++){
  140.             write_LONG(0UL, *(to.Strips_ByteCount + i) );
  141.             }
  142.         }
  143.     else{
  144.         Strip_Offset=*(to.Strip_Offset);
  145.         Strips_ByteCount=*(to.Strips_ByteCount);
  146.         }
  147.  
  148.     /* Color_Map の書き込み */
  149.     if( to.Photo_Interp==3 ){
  150.         j = 1<<to.Bits_Per_Sample;
  151.         Color_Map=ftell(to.fp);
  152.         for(i=0; i<j; i++)
  153.             write_SHORT(0UL, *(to.RED  +i) );
  154.         for(i=0; i<j; i++)
  155.             write_SHORT(0UL, *(to.GREEN+i) );
  156.         for(i=0; i<j; i++)
  157.             write_SHORT(0UL, *(to.BLUE +i) );
  158.         }
  159.  
  160.     /* Bits Per Sample の24ビットの場合 */
  161.     if(to.Bits_Per_Sample == 24){
  162.         BPS_offset = ftell(to.fp);
  163.         write_SHORT(0UL, 8);
  164.         write_SHORT(0UL, 8);
  165.         write_SHORT(0UL, 8);
  166.         BPS_len = 3;
  167.         }
  168.     else{
  169.         BPS_len = 1;
  170.         }
  171.  
  172.     /* IFD offset の書き込み。 */
  173.     write_LONG( 4UL, ftell(to.fp) );
  174.  
  175.     /* IFD field entry の書き込み */
  176.     if(to.Photo_Interp == 3) write_SHORT(0UL,17);
  177.                         else write_SHORT(0UL,16);
  178.  
  179.     write_entry(0xfe , LONG_TYPE, 1UL, to.New_Subfile_Type);
  180.     write_entry(0x100, SHORT_TYPE, 1UL, UL_ to.Image_Width);
  181.     write_entry(0x101, SHORT_TYPE, 1UL, UL_ to.Image_Length);
  182.  
  183.     if(BPS_len == 3)
  184.         write_entry(0x102, SHORT_TYPE, 3UL, UL_ BPS_offset);
  185.     else
  186.         write_entry(0x102, SHORT_TYPE, 1UL, UL_ to.Bits_Per_Sample);
  187.  
  188.     write_entry(0x103, SHORT_TYPE, 1UL, UL_ to.Compression);
  189.     write_entry(0x106, SHORT_TYPE, 1UL, UL_ to.Photo_Interp);
  190.     write_entry(0x10a, SHORT_TYPE, 1UL, UL_ to.Fill_Order);
  191.     write_entry(0x111, LONG_TYPE, UL_ to.Strips, UL_ Strip_Offset);
  192.     write_entry(0x115, SHORT_TYPE, 1UL , UL_ to.Samples_Per_Pixel);
  193.     write_entry(0x116, LONG_TYPE, 1UL, UL_ to.Rows_Per_Strip);
  194.     write_entry(0x117, LONG_TYPE, UL_ to.Strips, UL_ Strips_ByteCount);
  195.     write_entry(0x119, SHORT_TYPE,1UL, UL_ to.Max_Sample_Value);
  196.     write_entry(0x11a, RATIONAL_TYPE, 1UL, X_Res);
  197.     write_entry(0x11b, RATIONAL_TYPE, 1UL, Y_Res);
  198.     write_entry(0x11c, SHORT_TYPE, 1UL, UL_ to.Planer_Config);
  199.     write_entry(0x128, SHORT_TYPE, 1UL, 2UL);
  200.     if( to.Photo_Interp==3 )
  201.         write_entry(0x140, SHORT_TYPE, UL_(j*3UL), Color_Map);
  202.  
  203.     write_LONG(0UL,0UL);
  204.     return;
  205.  
  206.     TOWNS:
  207.     return;
  208. }
  209.  
  210.  
  211. /*
  212. 画像データを複数ブロックに分ける必要が出たため。
  213. ブロック化をと圧縮(関数呼びだし)をサポートする。
  214. data=256: バッファーのフラッシュ
  215. */
  216. void write_Gdata(unsigned short data)
  217. {
  218.     unsigned static char *add, *pc;
  219.     unsigned static long stack_bytes=0;    /* RAM内にためてあるバイト数 */
  220.     unsigned static long put_bytes=0;
  221.     static int INIT=0;
  222.     unsigned static long strip_size, strip_offset;
  223.  
  224.     if(INIT == 0){
  225.         strip_size=to.Image_Width * to.Rows_Per_Strip * (to.Bits_Per_Sample/8);
  226.         if(to.Compression == 1) pc=add=MALLOC( TEMP_SIZE );
  227.                            else pc=add=MALLOC( strip_size );
  228.         strip_offset=ftell(to.fp);
  229.         INIT=1;
  230.         }
  231.  
  232.     /* 1ストライプのデータが埋まった or データ終了時の処理 */
  233.     if( (put_bytes>=strip_size) || (data==256) ){
  234.         if( stack_bytes == 0 ) return;    /* 出力するデータがないとき */
  235.         printf("\r\t\t\t\t\t\t\rLine %3d : ",(to.Strips+1)*(to.Rows_Per_Strip) );
  236.         *(to.Strip_Offset + to.Strips) = strip_offset;
  237.  
  238.         if( to.Compression == 5){
  239.             compress(add, stack_bytes);
  240.             }
  241.         else{
  242.             fwrite(add, stack_bytes, 1, to.fp);
  243.             stack_bytes = ftell( to.fp ) - strip_offset;
  244.             printf("Write %lu bytes\n",stack_bytes);
  245.             *(to.Strips_ByteCount + to.Strips) = stack_bytes;
  246.             }
  247.  
  248.         to.Strips++;
  249.         strip_offset = ftell(to.fp);
  250.         pc=add;
  251.         stack_bytes = put_bytes = 0;
  252.  
  253.         if( data==256 ){
  254.             free(add);
  255.             INIT=0;
  256.             return;
  257.             };
  258.         };
  259.  
  260.     /* RAM内にためてあるデータが、一定量(TEMP_SIZE)を越して、出力するとき */
  261.     if( (to.Compression==1) && (stack_bytes==TEMP_SIZE) ){
  262.         printf("\rWrite %lu bytes(%d%)\t\t\t\t\t\r",TEMP_SIZE,100*put_bytes/strip_size);
  263.         fwrite(add, TEMP_SIZE, 1, to.fp);
  264.         stack_bytes = 0;
  265.         pc = add;
  266.         }
  267.  
  268.     *pc=data;    /* コンパイラーによって違う処理をするそうです */
  269.     pc++;
  270.     stack_bytes++;
  271.     put_bytes ++;
  272.     return;
  273. }
  274.